package lib.Com;

import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server extends Thread{
	/*
	 * TCPServer with multithreaded functionality handled by a automated ThreadPool.
	 */
	protected ServerSocket serverSocket;
    protected Socket client;
    
    protected int serverPort;
    protected boolean isStopped;
    
    protected Thread runningThread;
    protected ExecutorService threadPool;
    
    public Server() {
    	super("TCPServer");
    	this.serverPort = Container.Port1;
        this.isStopped = false;
        this.runningThread = null;
        this.threadPool = Executors.newFixedThreadPool(10);
    }
	
    public void run(){
        synchronized(this){
            this.runningThread = Thread.currentThread();
        }
        openServerSocket();
        while(! isStopped()){
            Socket clientSocket = null;
            try {
                clientSocket = this.serverSocket.accept();
            } catch (IOException e) {
                if(isStopped()) {
                    return;
                }
                throw new RuntimeException(
                    "Error accepting client connection", e);
            }
            
            this.threadPool.execute(new ServerWorker(clientSocket, "Thread Pooled Server"));
        }
        this.threadPool.shutdown();
    }
    
    private synchronized boolean isStopped() {
        return this.isStopped;
    }

    public synchronized void Stop(){
        this.isStopped = true;
        try {
            this.serverSocket.close();
        } catch (IOException e) {
            throw new RuntimeException("Error closing server", e);
        }
    }

    private void openServerSocket() {
        try {
            this.serverSocket = new ServerSocket(this.serverPort);
        } catch (IOException e) {
            throw new RuntimeException("Cannot open port " + this.serverPort , e);
        }
    }
    
}
